import {reroute} from './reroute';
// 重载路由控制 从而实现切换路由时切换应用
    // 关键点在于前端路由（hashchange、popstate）和浏览器路由（history.pushState、history.replaceState）

export const routingEventsListeningTo = ['hashchange','popstate'];

function urlReroute() {
    // 根据路径 重新加载不同的应用
    reroute([],arguments);
}
// 暂存钩子其他的监听事件 执行完状态机的逻辑后再执行
const captureEventListeners = {
    hashchange: [],
    popstate: []
}

window.addEventListener('hashchange',urlReroute);
window.addEventListener('popstate',urlReroute);

// 注意：子应用可能也会监听这两个事件，这就意味着 状态机执行完自己的逻辑后 还需要执行此API监听的其他函数

const originalAddEventListener = window.addEventListener;
const originalRemoveEventListener = window.removeEventListener;

window.addEventListener = function (eventName,fn) {
    if (routingEventsListeningTo.indexOf(eventName) >= 0 && !captureEventListeners[eventName].some(listener=>listener == fn) ) {
        captureEventListeners[eventName].push(fn);
        return;
    }else {
        return originalAddEventListener.apply(this,arguments);
    }
}

window.removeEventListener = function (eventName,fn) {
    if (routingEventsListeningTo.indexOf(eventName) >= 0) {
        captureEventListeners[eventName] = captureEventListeners[eventName].filter(l => l !== fn);
    }else {
        originalRemoveEventListener.apply(this,arguments)
    }
}

// 浏览器路由（history.pushState、history.replaceState）

function patchedUpdateState(updateState,methodName) {
    return function () {
        const urlBefore = window.location.href;
        updateState.apply(this,arguments); // 调用切换方法
        const urlAfter = window.location.href;
        // 如果路由发生改变 则执行页面更新逻辑
        if (urlAfter !== urlBefore) {
            urlReroute(new PopStateEvent('popstate'));
            
        }
    }
}

window.history.pushState = patchedUpdateState(window.history.pushState,'pushState');
window.history.replaceState = patchedUpdateState(window.history.replaceState,'replaceState');